package com.gitee.wsl.collections.iterator

import com.gitee.wsl.func.predicate.Predicate


/**
 * Iterates over the elements of the iterator until predicate returns false.
 *
 * @since 8.0
 */
class TakeWhileIterator<T>(
    private val iterator: Iterator<T>,
    private val predicate: Predicate<in T>
) : Iterator<T> {
    private var terminate = false
    private var next: Any? = NULL

    constructor(iterable: Iterable<T>, predicate: Predicate<in T>) : this(iterable.iterator(), predicate)

    public override fun hasNext(): Boolean {
        if (this.next !== NULL) {
            return true
        }
        if (!this.terminate && this.iterator.hasNext()) {
            val temp = this.iterator.next()
            if (this.predicate.accept(temp)) {
                this.next = temp
                return true
            }

            this.terminate = true
            this.next = NULL
        }
        return false
    }

    public override fun next(): T {
        if (this.hasNext()) {
            val temp = this.next
            this.next = NULL
            return temp as T
        }
        throw NoSuchElementException()
    }


    companion object {
        private val NULL = Any()
    }
}
